package com.hudson.broker.monitor;

import com.hudson.broker.concurrent.HudsonThreadFactory;
import com.hudson.broker.concurrent.TimerScheduledThreadPool;
import com.hudson.broker.concurrent.TimerThreadPool;
import com.hudson.broker.concurrent.TimerThreadPoolSpec;
import com.hudson.core.json.JSONUtil;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.util.HashedWheelTimer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.*;

public class ThreadPoolHelper {
    private static final Logger logger = LoggerFactory.getLogger(ThreadPoolHelper.class);

    public static ConcurrentHashMap<String, TimerThreadPoolSpec> threadPoolConcurrentHashMap = new ConcurrentHashMap<>();


    public static NioEventLoopGroup BROKER_BOSS_EVENT_LOOP = new NioEventLoopGroup(2);

    public static NioEventLoopGroup BROKER_WORK_EVENT_LOOP = new NioEventLoopGroup(30);

    public static NioEventLoopGroup NAME_SRV_WORK_EVENT_LOOP = new NioEventLoopGroup(5);


    public static TimerScheduledThreadPool DEFAULT_SCHEDULED_POOL = new TimerScheduledThreadPool("default-scheduled-pool",
            10, new HudsonThreadFactory("default-scheduled"));

    public static TimerThreadPool DEFAULT_THREAD_POOL = new TimerThreadPool(
            "default-thread-pool", 20, 40, 30, TimeUnit.SECONDS, new LinkedBlockingQueue<>(), new HudsonThreadFactory("default-scheduled"));

    public static HashedWheelTimer WHEEL_TIMER = new HashedWheelTimer(
            new HudsonThreadFactory("relay-message-thread"), 1, TimeUnit.SECONDS);

    static {
        threadPoolConcurrentHashMap.put(DEFAULT_SCHEDULED_POOL.getPoolName(), DEFAULT_SCHEDULED_POOL);
        threadPoolConcurrentHashMap.put(DEFAULT_THREAD_POOL.getPoolName(), DEFAULT_THREAD_POOL);
    }

    public static Map<String, Map<String, Object>> getBrokerWatchData() {
        Map<String, Map<String, Object>> result = new HashMap<>();
        for (Map.Entry<String, TimerThreadPoolSpec> entry : threadPoolConcurrentHashMap.entrySet()) {
            result.put(entry.getKey(), entry.getValue().getWatchDate());
        }
        return result;
    }

    static {
        ThreadPoolHelper.DEFAULT_SCHEDULED_POOL.scheduleAtFixedRateByWatch(() -> {
            logger.debug("{}", JSONUtil.toJson(getBrokerWatchData()));
        }, 20, 20, TimeUnit.SECONDS);

//        ThreadPoolHelper.DEFAULT_SCHEDULED_POOL.scheduleAtFixedRateByWatch(() -> {
//            ResourceMonitor.getMemoryResource();
//            ResourceMonitor.cpuUsage();
//            ResourceMonitor.diskUsage();
//        }, 10, 10, TimeUnit.SECONDS);
    }

    public static void shutDown(){
        ThreadPoolHelper.BROKER_BOSS_EVENT_LOOP.shutdownGracefully();
        ThreadPoolHelper.BROKER_WORK_EVENT_LOOP.shutdownGracefully();
        ThreadPoolHelper.NAME_SRV_WORK_EVENT_LOOP.shutdownGracefully();
        ThreadPoolHelper.NAME_SRV_WORK_EVENT_LOOP.shutdownGracefully();
        ThreadPoolHelper.DEFAULT_SCHEDULED_POOL.shutdown();
    }
}
